package com.asiainfo.dacp.datastash.broker.flow.core.repo;

import java.util.Date;
import java.util.GregorianCalendar;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.asiainfo.dacp.datastash.broker.common.enums.UnitRunningStateEnum;
import com.asiainfo.dacp.datastash.broker.common.enums.UnitStateEnum;
import com.asiainfo.dacp.datastash.broker.flow.core.domain.Flow;
import com.asiainfo.dacp.datastash.orm.dao.log.DataStashUnitEventLogDao;
import com.asiainfo.dacp.datastash.orm.dao.state.DataStashUnitStateLogDao;
import com.asiainfo.dacp.datastash.orm.po.log.DataStashUnitEventLogPo;
import com.asiainfo.dacp.datastash.orm.po.state.DataStashUnitStateLogPo;
import com.asiainfo.dacp.util.BeanConvertUtils;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;

@Repository
public class UnitStateRepository {
	@Autowired
	private DataStashUnitStateLogDao stateDao;

	@Autowired
	private DataStashUnitEventLogDao logDao;

	public void createOrUpdate(Flow flow) {
		Preconditions.checkNotNull(flow);
		DataStashUnitStateLogPo statePo = buildState(flow);
		stateDao.save(statePo);
		DataStashUnitEventLogPo logPo = buildStateLog(statePo);
		logDao.save(logPo);
	}

	private DataStashUnitStateLogPo buildState(Flow flow) {
		String serNo = flow.getSerNo();
		DataStashUnitStateLogPo statePo = stateDao.findOne(serNo);
		if (statePo == null) {
			statePo = new DataStashUnitStateLogPo();
			statePo.setUnitProcId(flow.getSerNo());
			statePo.setUnitCode(flow.getUnitCode());
			statePo.setBatchNo(flow.getBatchNo());
			statePo.setCreateDt(new Date());
			statePo.setIsOver(UnitRunningStateEnum.RUNNING.value());
		}
		UnitStateEnum state = flow.getUnitState();
		statePo.setState(state.value());

		statePo.setTaskCnt(flow.getTaskCnt());

		if (Strings.isNullOrEmpty(flow.getRemark())) {
			statePo.setMessage(state.label());
		} else {
			statePo.setMessage(flow.getRemark());
		}

		statePo.setLastupd(new Date());
		// TODO add brokerid |broker ip
		if (UnitStateEnum.RUNNABLE == state) {
			statePo.setStartDt(new Date());
		} else if (UnitStateEnum.SUCESS == state) {
			statePo.setIsOver(UnitRunningStateEnum.END.value());
			statePo.setCompleteDt(new Date());
		}
		return statePo;
	}

	private DataStashUnitEventLogPo buildStateLog(DataStashUnitStateLogPo unitStatePo) {
		DataStashUnitEventLogPo logPo = null;
		String state = unitStatePo.getState();
		String unitProcId = unitStatePo.getUnitProcId();
		if (!Strings.isNullOrEmpty(state) && !Strings.isNullOrEmpty(unitProcId)) {
			if (UnitStateEnum.BLOCKED_RELAY.value().equals(state) ) {
				logPo = logDao.findByUnitProcIdAndState(unitProcId, state);
			}
		}
		if (logPo != null) {
			// TODO update retry_cnt && brokerIp
		} else {
			logPo = BeanConvertUtils.copyBean(unitStatePo, DataStashUnitEventLogPo.class);
			logPo.setCreateDt(new Date());
		}
		return logPo;
	}
}
